/*
 * The contents of this web application are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this web application except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the License.
 * 
 * The Original Code is owned by and the Initial Developer of the Original Code is 
 * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
 * 
 * Section 11 of the License is EXPRESSLY amended to include a provision stating 
 * that any dispute, including but not limited to disputes related to the enforcement 
 * of the License, to which Composite A/S as owner of the Original Code, as Initial 
 * Developer or in any other role, becomes a part to shall be governed by Danish law 
 * and be initiated before the Copenhagen City Court ("K�benhavns Byret")            
 */

using System.CodeDom;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;


namespace Composite.Plugins.Data.DataProviders.MSSqlServerDataProvider.CodeGeneration
{
    internal static class EntityCodeGeneratorHelper
    {
        public static string GetDbType(SqlDbType dbType, bool isNullable)
        {
            string s = dbType.ToString().ToLowerInvariant();
            if (s == "varchar") s = "nvarchar";

            return string.Format("{0}{1}", s, isNullable ? "" : " NOT NULL");
        }



        public static void AddPropertyChanging(CodeTypeDeclaration declaration)
        {
            CodeMemberEvent changingEvent = new CodeMemberEvent();
            changingEvent.Name = "PropertyChanging";
            changingEvent.Type = new CodeTypeReference(typeof(PropertyChangingEventHandler));
            changingEvent.Attributes = MemberAttributes.Public;

            declaration.Members.Add(changingEvent);


            CodeMemberMethod changingMethod = new CodeMemberMethod();
            changingMethod.Name = "OnPropertyChanging";
            changingMethod.ReturnType = new CodeTypeReference(typeof(void));
            changingMethod.Attributes = MemberAttributes.Family;
            changingMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "propertyName"));
            changingMethod.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(DebuggerNonUserCodeAttribute))));



            changingMethod.Statements.Add(new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(
                        new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanging"),
                        CodeBinaryOperatorType.IdentityInequality,
                        new CodePrimitiveExpression(null)
                    ),
                    new CodeStatement[] {
                        new CodeExpressionStatement(
                            new CodeMethodInvokeExpression(
                                new CodeThisReferenceExpression(),
                                "PropertyChanging",
                                new CodeExpression[] {
                                    new CodeThisReferenceExpression(),
                                    new CodeObjectCreateExpression(
                                        typeof(PropertyChangingEventArgs),
                                        new CodeExpression[] {
                                            new CodeArgumentReferenceExpression("propertyName")
                                        }
                                    )
                                }
                            )
                        )
                    }
                ));

            declaration.Members.Add(changingMethod);
        }



        public static void AddPropertyChanged(CodeTypeDeclaration declaration)
        {
            CodeMemberEvent changingEvent = new CodeMemberEvent();
            changingEvent.Name = "PropertyChanged";
            changingEvent.Type = new CodeTypeReference(typeof(PropertyChangedEventHandler));
            changingEvent.Attributes = MemberAttributes.Public;

            declaration.Members.Add(changingEvent);


            CodeMemberMethod changingMethod = new CodeMemberMethod();
            changingMethod.Name = "OnPropertyChanged";
            changingMethod.ReturnType = new CodeTypeReference(typeof(void));
            changingMethod.Attributes = MemberAttributes.Family;
            changingMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "propertyName"));
            changingMethod.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(DebuggerNonUserCodeAttribute))));


            changingMethod.Statements.Add(new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(
                        new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanged"),
                        CodeBinaryOperatorType.IdentityInequality,
                        new CodePrimitiveExpression(null)
                    ),
                    new CodeStatement[] {
                        new CodeExpressionStatement(
                            new CodeMethodInvokeExpression(
                                new CodeThisReferenceExpression(),
                                "PropertyChanged",
                                new CodeExpression[] {
                                    new CodeThisReferenceExpression(),
                                    new CodeObjectCreateExpression(
                                        typeof(PropertyChangedEventArgs),
                                        new CodeExpression[] {
                                            new CodeArgumentReferenceExpression("propertyName")
                                        }
                                    )
                                }
                            )
                        )
                    }
                ));


            declaration.Members.Add(changingMethod);
        }
    }
}
